﻿using System;
using System.ComponentModel;
using System.Runtime.Remoting;
using System.Security.Permissions;
using Chambills.Present.Core;

namespace Present.Commands.Decorators
{
    /// <summary>
    /// Implements <see cref="IBackgroundWorker" /> by wrapping <see cref="BackgroundWorker" />
    /// Useful for testing and Classes that want to transparently swap between Synch and Asynch behaviour
    /// </summary>
    public class BackgroundWorkerDecorator : ManagedDisposable, IBackgroundWorker
    {
        private readonly BackgroundWorker worker;

        public BackgroundWorkerDecorator()
        {
            worker = new BackgroundWorker();
        }

        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
        public object GetLifetimeService()
        {
            return worker.GetLifetimeService();
        }

         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
        public object InitializeLifetimeService()
        {
            return worker.InitializeLifetimeService();
        }

         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
        public ObjRef CreateObjRef(Type requestedType)
        {
            return worker.CreateObjRef(requestedType);
        }

        protected override void DisposeResources()
        {
            base.DisposeResources();
            worker.Dispose();
        }

        public ISite Site
        {
            get { return worker.Site; }
            set { worker.Site = value; }
        }

        public IContainer Container
        {
            get { return worker.Container; }
        }

        public event EventHandler Disposed
        {
            add { worker.Disposed += value; }
            remove { worker.Disposed -= value; }
        }

        public void CancelAsync()
        {
            worker.CancelAsync();
        }

        public void ReportProgress(int percentProgress)
        {
            worker.ReportProgress(percentProgress);
        }

        public void ReportProgress(int percentProgress, object userState)
        {
            worker.ReportProgress(percentProgress, userState);
        }

        public void RunWorkerAsync()
        {
            worker.RunWorkerAsync();
        }

        public void RunWorkerAsync(object argument)
        {
            worker.RunWorkerAsync(argument);
        }

        public bool CancellationPending
        {
            get { return worker.CancellationPending; }
        }

        public bool IsBusy
        {
            get { return worker.IsBusy; }
        }

        public bool WorkerReportsProgress
        {
            get { return worker.WorkerReportsProgress; }
            set { worker.WorkerReportsProgress = value; }
        }

        public bool WorkerSupportsCancellation
        {
            get { return worker.WorkerSupportsCancellation; }
            set { worker.WorkerSupportsCancellation = value; }
        }

        public event DoWorkEventHandler DoWork
        {
            add { worker.DoWork += value; }
            remove { worker.DoWork -= value; }
        }

        public event ProgressChangedEventHandler ProgressChanged
        {
            add { worker.ProgressChanged += value; }
            remove { worker.ProgressChanged -= value; }
        }

        public event RunWorkerCompletedEventHandler RunWorkerCompleted
        {
            add { worker.RunWorkerCompleted += value; }
            remove { worker.RunWorkerCompleted -= value; }
        }
    }
}
